///@file ElastoplasticMaterial.h
///@brief Declaration of the class representing a linear elastic material with isotropic hardening plastic behaviour
///@author Arnaud Duval
///@version 0.0
///@date 2011/03/10


#ifndef ELASTOPLASTICMATERIAL_H
#define ELASTOPLASTICMATERIAL_H

#include "Material.h"
#include "StressVector.h"
#include "Tensor4.h"

///@class ElastoplasticMaterial
///@brief Class defining an elastoplastic material
class ElastoplasticMaterial : public Material
{
    private:
        ///@brief Young modulus
        double young;
        ///@brief Poisson coefficient
        double poisson;
        ///@brief First isotropic hardening coefficient
        double Hiso;
        ///@brief Second isotropic hardening coefficient
        double n;
        ///@brief Yield stress
        double sigmaY;

    protected:
        ///@brief Compute residuals
        Vector ComputeResiduals(Tensor2, Tensor2, double, double, Tensor2, Tensor2, Tensor2);
        ///@brief Compute residuals
        Vector ComputeResiduals(StressVector, StressVector, double, double, Vector, Vector, Vector);
        ///@brief Compute residuals derivatives
        Matrix ComputeResidualsDerivatives(Tensor2, Tensor2, double, double, Tensor2, Tensor2, Tensor2);
        ///@brief Compute residuals derivatives
        Matrix ComputeResidualsDerivatives(StressVector, StressVector, double, double, Vector, Vector, Vector);
        
    public:
        ///@brief Default constructor
        ElastoplasticMaterial();
        ///@brief Destructor
        ~ElastoplasticMaterial();
        ///@brief Constructor with arguments
        ElastoplasticMaterial(double, double, double, double, double);
        ///@brief Set the value of a given parameter
        void SetParameter(int, double);
        ///@brief Compute stess tensor increment from strain tensor tensor increment and initial stress and strain
        StressTensor Dstress(StrainTensor, StressTensor, StrainTensor);
        ///@brief Print output
        void PrintOutput(std::ostream &);
        ///@brief Similar to an Abaqus UMAT
        virtual bool UMAT(const Vector&, const Vector&, Vector&, Matrix&, double*, unsigned int);
        ///@brief Return elastic stiffness fourth order tensor
        Tensor4 StiffnessTensor(unsigned int);
        ///@brief Return elastic stiffness matrix
        Matrix StiffnessMatrix(unsigned int);
        ///@brief Return elastic compliance fourth order tensor
        Tensor4 ComplianceTensor(unsigned int);
        ///@brief Return elastic compliance matrix
        Matrix ComplianceMatrix(unsigned int);
        ///@brief Compute the loading function
        double LoadingFunction(Tensor2, double);
        ///@brief Compute the loding function
        double LoadingFunction(StressVector, double);
        
};

#endif
